﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Wintellect.PowerCollections;
using System.IO;
using System.Xml;
using System.Collections;
using System.Collections.ObjectModel;

namespace DbSharp.Framework.Storage.IO
{
    public class RecordsetXElmtTextWriter
    {
        #region Private members
        private StringBuilder m_StrBuilder = new StringBuilder();
        private List<string> m_ListElementStr = new List<string>();
        #endregion

 

        /// <summary>
        /// Make sure one row is in one line 
        /// </summary>
        /// <param name="rcdsetElement"></param>
        /// <param name="exportRecordCount"></param>
        public RecordsetXElmtTextWriter(IEnumerable<XElement> rcdsetElement, bool storeWithStringBuilder, long exportRecordCount)
        {
            if (storeWithStringBuilder)
                FillStringBuilder(rcdsetElement, exportRecordCount);
            else
                FillStringList(rcdsetElement, exportRecordCount);
        }


        #region Private methods

        private void FillStringList(IEnumerable<XElement> rcdsetElement, long exportRecordCount)
        {
            long exportRecordLimited = long.MaxValue;
            if (exportRecordCount >= 0)
                exportRecordLimited = exportRecordCount;

            long index = 0;
            foreach (var item in rcdsetElement)
            {
                if (index >= exportRecordLimited)
                    break;
                index++;

                //only append data row (marked with "row" tag)
                m_ListElementStr.Add(item.ToString(SaveOptions.None));
            }
        }


        private void FillStringBuilder(IEnumerable<XElement> rcdsetElement, long exportRecordCount)
        {
            bool tailedByNewline = false;
            XmlWriterSettings xmlSettings = new XmlWriterSettings
            {
                OmitXmlDeclaration = true,
                ConformanceLevel = ConformanceLevel.Fragment,
                NewLineChars = string.Empty,
                NewLineHandling = NewLineHandling.None,
                NewLineOnAttributes = false,
                Encoding = Encoding.UTF8,
                Indent = false
            };

            using (XmlWriter xw = XmlWriter.Create(m_StrBuilder, xmlSettings))
            {
                m_StrBuilder.Length = 0;

                long exportRecordLimited = long.MaxValue;
                if (exportRecordCount >= 0)
                    exportRecordLimited = exportRecordCount;

                long index = 0;
                foreach (var item in rcdsetElement)
                {
                    if (index >= exportRecordLimited)
                        break;
                    index++;

                    //only append data row (marked with "row" tag)
                    item.WriteTo(xw);
                    xw.WriteRaw(Environment.NewLine);
                    tailedByNewline = true;
                }
            }

            //trim the last NewLine
            if (tailedByNewline)
                m_StrBuilder.Length = m_StrBuilder.Length - Environment.NewLine.Length;
        }

        #endregion


        #region Public property/method

        public StringBuilder StringBuilder
        {
            get { return m_StrBuilder; }
        }

        public ReadOnlyCollection<string> StringList
        {
            get { return new ReadOnlyCollection<string>(m_ListElementStr); }
        }
         
        #endregion
    }

}
